/***
 * * PROJECT
 * *    ATaG
 * * VERSION
 * *    $Revision: 1.4 $
 * * DATE
 * *    $Date: 2006/10/27 01:28:28 $
 * * LOG
 * *    $Log: DataItem.java,v $
 * *    Revision 1.4  2006/10/27 01:28:28  lmottola
 * *    Debugging support added.
 * *
 * *    Revision 1.3  2006/10/26 23:58:30  lmottola
 * *    Bug fixes: Hello World application running in SWANS.
 * *
 * *    Revision 1.2  2006/10/19 21:21:52  lmottola
 * *    Added CVS preamble.
 * *
 * *
 * *   ATaG (Abstract Task Graph) - Data-driven Macroprogramming for
 * *                                Sensor Networks
 * *
 * *   This program is free software; you can redistribute it and/or
 * *   modify it under the terms of the GNU General Public License
 * *   as published by the Free Software Foundation; either version 2
 * *   of the License, or (at your option) any later version.
 * *
 * *   This program is distributed in the hope that it will be useful,
 * *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 * *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * *   GNU General Public License for more details.
 * *
 * *   You should have received a copy of the GNU General Public License
 * *   along with this program; if not, you may find a copy at the FSF web
 * *   site at 'www.gnu.org' or 'www.fsf.org', or you may write to the
 * *   Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * *   Boston, MA  02111-1307, USA
 ***/

package atag.runtime;

import java.io.Serializable;
import java.util.Vector;

import atag.runtime.platformDependent.ArchConstants;

public class DataItem implements Serializable{

  private String m_timeStamp;
  private String m_dateStamp;

  private int m_originID;
  private NodeLocation m_originLocation;
  private Vector<Object> m_coreVector;
  private int[] m_totalRefs;
  private int[] m_nowRefs;
  private int m_dataID;
  private int m_producerTaskID;

  public DataItem(int t_ID, int t_producerTaskID, Object t_coreData) {
    m_coreVector = new Vector(1);
    m_coreVector.add(t_coreData);
    m_dataID = t_ID;
    m_producerTaskID = t_producerTaskID;
    m_totalRefs = new int[ArchConstants.MAXTASKS];
    m_nowRefs = new int[ArchConstants.MAXTASKS];
  }

  public Object core() {
    return m_coreVector.get(0);
  }

  public void setOriginID(int t_origID) {
    m_originID = t_origID;
  }

  public void setOriginLocation(NodeLocation t_origLocation) {
    m_originLocation = t_origLocation;
  }

  public void setTimeStamp(String t_time) {
    m_timeStamp = t_time;
  }

  public void setDateStamp(String t_date) {
    m_dateStamp = t_date;
  }

  // Do the following 2 need corresponding getRef methods?
  public void setTotalReferences(int[] t_totalRefs) {
    m_totalRefs = t_totalRefs;
  }
  public void setNowReferences(int[] t_nowRefs) {
    m_nowRefs = t_nowRefs;
  }

  /** This is called only by getData.  Hence, nowRefs and totalRefs should both
   * be 1 for this index; the AtagManager should have set that before scheduling
   * this task that is calling the getData.  Hence check that both are 1.
   */
  public void decrementRef(int taskID) {
    if (m_totalRefs[taskID] != 1 || m_nowRefs[taskID] != 1) {
      System.err.println("total and now_refs are not both one. Why? task: " + taskID);
      System.exit(-1);
    } else {
      m_totalRefs[taskID]--;
      m_nowRefs[taskID]--;
    }
  }

  public int dataID() {
    return m_dataID;
  }

  public int producerID() {
    return m_producerTaskID;
  }

  public int originID() {
    return m_originID;
  }

  public NodeLocation originLocation() {
    return m_originLocation;
  }

  public String timeStamp() {
    return m_timeStamp;
  }

  public String dateStamp() {
    return m_dateStamp;
  }

  public boolean isActive() {
    for (int ctr=0; ctr<m_nowRefs.length; ctr++)
      if (m_nowRefs[ctr] == 1)
        return true;
    return false;
  }

  /** This is called by DataPool at the reqeust of AtagManager to check if
   * the item is 'available' so that a task could be scheduled.  Hence check
   * only totalRefs because nowRefs will typically be zero at this time.
   * Only after all isAlive calls are over with total and nowRefs be
   * initialized by the AtagManager, depending on the result of the calls.
   */

  public boolean isAlive(int taskID) {
    if (m_totalRefs[taskID] == 1)
      return true;
    else
      return false;
  }

}
